import { Request, Response } from 'express';
import { AuthRequest } from '@/types';
import roleService from '@/services/system/role.service';
import menuService from '@/services/system/menu.service';
import deptService from '@/services/system/dept.service';
import { getLogger } from '@/utils/logger';
import ApiResponse from '@/utils/api/api-response.util';
import ExcelUtil from '@/utils/excel/excel.util';
import { Log, BusinessType } from '@/decorators/Log';
import { RepeatSubmit } from '@/decorators/repeatSubmit.decorator';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("role-controller");
const logger = getLogger("role-controller", {
	console: false,
});

class RoleController {
  /**
   * 获取角色列表
   */
  async list(req: Request, res: Response){
    try {
      const { pageNum = 1, pageSize = 10, ...params } = req.query;
      
      // 请求日志
      consoleLogger.info("获取角色列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const result = await roleService.listRolesByPage(
        params,
        Number(pageNum),
        Number(pageSize)
      );
      
      // 结果日志
      logger.info("获取角色列表成功", {
        response: {
          total: result.total,
          count: result.rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithTable(
        res, 
        result.rows, 
        result.total, 
        '查询成功',
        Number(pageNum),
        Number(pageSize)
      );
    } catch (error: any) {
      consoleLogger.error(`获取角色列表失败: ${error.message}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败');
      }
    }
  }

  /**
   * 获取角色详细信息
   */
  async getInfo(req: Request, res: Response){
    try {
      const roleId = Number(req.params.roleId);
      
      // 请求日志
      consoleLogger.info("获取角色详细信息请求", {
        params: req.params,
        operator: req.user?.userName || 'unknown',
      });
      
      const role = await roleService.selectRoleById(roleId);
      if (!role) {
        ApiResponse.notFound(res, '角色不存在');
        return;
      }
      
      // 结果日志
      logger.info("获取角色详细信息成功", {
        response: {
          roleId,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, role, '查询成功');
    } catch (error: any) {
      consoleLogger.error(`获取角色详细信息失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败');
      }
    }
  }

  /**
   * 获取角色菜单树
   */
  async roleMenuTreeselect(req: Request, res: Response){
    try {
      const roleId = Number(req.params.roleId);
      
      // 请求日志
      consoleLogger.info("获取角色菜单树请求", {
        params: req.params,
        operator: req.user?.userName || 'unknown',
      });
      
      // 获取菜单树
      const menuTree = await menuService.selectMenuTreeByRoleId(roleId);
      
      // 获取角色关联的菜单ID列表
      const checkedKeys = await roleService.getRoleMenuIds(roleId);
      
      // 结果日志
      logger.info("获取角色菜单树成功", {
        response: {
          roleId,
          checkedKeysCount: checkedKeys.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, {
        menus: menuTree,
        checkedKeys
      }, '查询成功');
    } catch (error: any) {
      consoleLogger.error(`获取角色菜单树失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败');
      }
    }
  }

  /**
   * 新增角色
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '角色管理', businessType: BusinessType.INSERT })
  async add(req: Request, res: Response){
    try {
      const role = req.body;
      
      // 请求日志
      consoleLogger.info("新增角色请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      // 设置创建者
      role.createBy = (req as any).user?.userName || 'admin';
      
      // 新增角色
      const result = await roleService.insertRole(role);
      
      // 结果日志
      logger.info("新增角色成功", {
        response: {
          roleId: result.roleId,
          roleName: result.roleName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '新增成功');
    } catch (error: any) {
      consoleLogger.error(`新增角色失败: ${error.message}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '新增失败');
      }
    }
  }

  /**
   * 修改角色
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '角色管理', businessType: BusinessType.UPDATE })
  async update(req: Request, res: Response){
    try {
      const role = req.body;
      
      // 请求日志
      consoleLogger.info("修改角色请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      // 设置更新者
      role.updateBy = (req as any).user?.userName || 'admin';
      
      // 修改角色
      const updatedRole = await roleService.updateRole(role);
      
      // 结果日志
      logger.info("修改角色成功", {
        response: {
          roleId: role.roleId,
          roleName: role.roleName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, updatedRole, '修改成功');
    } catch (error: any) {
      consoleLogger.error(`修改角色失败: ${error.message}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '修改失败');
      }
    }
  }

  /**
   * 删除角色
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '角色管理', businessType: BusinessType.DELETE })
  async remove(req: Request, res: Response){
    try {
      const roleIds = req.params.roleIds.split(',').map(Number);
      
      // 请求日志
      consoleLogger.info("删除角色请求", {
        params: req.params,
        roleIds,
        operator: req.user?.userName || 'unknown',
      });
      
      // 删除角色
      await roleService.deleteRoleByIds(roleIds);
      
      // 结果日志
      logger.info("删除角色成功", {
        response: {
          roleIds,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '删除成功');
    } catch (error: any) {
      consoleLogger.error(`删除角色失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '删除失败');
      }
    }
  }

  /**
   * 获取所有角色列表
   */
  async optionselect(req: Request, res: Response){
    try {
      // 请求日志
      consoleLogger.info("获取所有角色列表请求", {
        operator: req.user?.userName || 'unknown',
      });
      
      const roles = await roleService.selectRoleAll();
      
      // 结果日志
      logger.info("获取所有角色列表成功", {
        response: {
          count: roles.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, roles, '查询成功');
    } catch (error: any) {
      consoleLogger.error(`获取所有角色列表失败: ${error.message}`, {
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败');
      }
    }
  }

  /**
   * 检查用户是否有指定权限
   */
  async checkPermission(req: Request, res: Response){
    try {
      const { userId, permission } = req.body;
      
      // 请求日志
      consoleLogger.info("检查用户权限请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      const hasPermission = await roleService.hasPermission(userId, permission);
      
      // 结果日志
      logger.info("检查用户权限成功", {
        response: {
          userId,
          permission,
          hasPermission,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, { hasPermission }, '查询成功');
    } catch (error: any) {
      consoleLogger.error(`检查用户权限失败: ${error.message}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败');
      }
    }
  }

  /**
   * 获取用户数据权限范围
   */
  async getUserDataScope(req: Request, res: Response){
    try {
      const userId = Number(req.params.userId);
      
      // 请求日志
      consoleLogger.info("获取用户数据权限范围请求", {
        params: req.params,
        userId,
        operator: req.user?.userName || 'unknown',
      });
      
      const dataScope = await roleService.getUserDataScope(userId);
      
      // 结果日志
      logger.info("获取用户数据权限范围成功", {
        response: {
          userId,
          dataScope,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, { dataScope }, '查询成功');
    } catch (error: any) {
      consoleLogger.error(`获取用户数据权限范围失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败');
      }
    }
  }

  /**
   * 查询已分配用户角色列表
   */
  async allocatedList(req: Request, res: Response){
    try {
      const roleId = parseInt(req.query.roleId as string);
      
      // 请求日志
      consoleLogger.info("查询已分配用户角色列表请求", {
        query: req.query,
        roleId,
        operator: req.user?.userName || 'unknown',
      });
      
      // 验证角色ID
      if (isNaN(roleId)) {
        ApiResponse.error(res, '无效的角色ID', 500);
        return;
      }
      
      const result = await roleService.getAllocatedUserList(req.query, roleId);
      
      // 结果日志
      logger.info("查询已分配用户角色列表成功", {
        response: {
          roleId,
          total: result.total,
          count: result.rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithTable(res, result.rows, result.total);
    } catch (error) {
      consoleLogger.error(`查询已分配用户角色列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '查询已分配用户角色列表失败', 500);
      }
    }
  }
  
  /**
   * 查询未分配用户角色列表
   */
  async unallocatedList(req: Request, res: Response){
    try {
      const roleId = parseInt(req.query.roleId as string);
      
      // 请求日志
      consoleLogger.info("查询未分配用户角色列表请求", {
        query: req.query,
        roleId,
        operator: req.user?.userName || 'unknown',
      });
      
      // 验证角色ID
      if (isNaN(roleId)) {
        ApiResponse.error(res, '无效的角色ID', 500);
        return;
      }
      
      const result = await roleService.getUnallocatedUserList(req.query, roleId);
      
      // 结果日志
      logger.info("查询未分配用户角色列表成功", {
        response: {
          roleId,
          total: result.total,
          count: result.rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithTable(res, result.rows, result.total);
    } catch (error) {
      consoleLogger.error(`查询未分配用户角色列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '查询未分配用户角色列表失败', 500);
      }
    }
  }

  /**
   * 角色数据权限
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '角色管理', businessType: BusinessType.UPDATE })
  async dataScope(req: AuthRequest, res: Response){
    try {
      const role = req.body;
      
      // 请求日志
      consoleLogger.info("设置角色数据权限请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      // 设置更新者
      role.updateBy = req.user?.userName || 'admin';
      
      // 修改数据权限
      await roleService.updateRoleDataScope(role, role.updateBy);
      
      // 结果日志
      logger.info("设置角色数据权限成功", {
        response: {
          roleId: role.roleId,
          dataScope: role.dataScope,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '设置成功');
    } catch (error: any) {
      consoleLogger.error(`设置角色数据权限失败: ${error.message}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '设置失败');
      }
    }
  }

  /**
   * 导出角色数据
   */
  async export(req: Request, res: Response){
    try {
      // 请求日志
      consoleLogger.info("导出角色数据请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      // 查询角色列表，设置pageSize为0获取所有数据
      const { rows } = await roleService.listRolesByPage(req.query, 1, 0);
      
      // 确保有数据
      if (!rows || rows.length === 0) {
        ApiResponse.error(res, '没有数据可导出', 400);
        return;
      }
      
      // 定义导出字段
      const fields = [
        { header: '角色序号', key: 'roleId', width: 10 },
        { header: '角色名称', key: 'roleName', width: 20 },
        { header: '角色权限', key: 'roleKey', width: 20 },
        { header: '角色排序', key: 'roleSort', width: 10 },
        { header: '数据范围', key: 'dataScope', width: 15, type: 'select', options: { 
          '1': '全部数据权限', 
          '2': '自定数据权限', 
          '3': '本部门数据权限', 
          '4': '本部门及以下数据权限', 
          '5': '仅本人数据权限' 
        }, formatter: (value: string): string => {
          const options: Record<string, string> = {
            '1': '全部数据权限', 
            '2': '自定数据权限', 
            '3': '本部门数据权限', 
            '4': '本部门及以下数据权限', 
            '5': '仅本人数据权限'
          };
          return options[value] || value;
        }},
        { header: '角色状态', key: 'status', width: 10, type: 'select', options: { '0': '正常', '1': '停用' }, formatter: (value: string): string => value === '0' ? '正常' : '停用' },
        { header: '创建时间', key: 'createTime', width: 20, type: 'datetime' },
        { header: '备注', key: 'remark', width: 30 }
      ];
      
      // 结果日志
      logger.info("导出角色数据准备完成", {
        response: {
          count: rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      // 使用导出到响应方法
      await ExcelUtil.exportToResponse(
        res,
        rows,
        fields,
        `role_${Date.now()}`,
        '角色数据'
      );

      ApiResponse.success(res, null, '导出成功');
    } catch (error: any) {
      consoleLogger.error(`导出角色失败: ${error.message}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '导出角色失败', 500);
      }
    }
  }
  
  /**
   * 获取部门树权限
   */
  async deptTreeSelect(req: Request, res: Response){
    try {
      // 请求日志
      consoleLogger.info("获取部门树权限请求", {
        operator: req.user?.userName || 'unknown',
      });
      
      // 获取部门树
      const deptTree = await deptService.selectDeptTreeList({});
      
      // 结果日志
      logger.info("获取部门树权限成功", {
        response: {
          count: deptTree.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, {
				depts: deptTree,
			});
    } catch (error: any) {
      consoleLogger.error(`获取部门树权限失败: ${error.message}`, {
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '获取部门树权限失败', 500);
      }
    }
  }
  
  /**
   * 根据角色ID查询部门树结构
   */
  async roleDeptTreeselect(req: Request, res: Response){
    try {
      const roleId = Number(req.params.roleId);
      
      // 请求日志
      consoleLogger.info("获取角色部门树请求", {
        params: req.params,
        roleId,
        operator: req.user?.userName || 'unknown',
      });
      
      // 获取部门树
      const deptTree = await deptService.selectDeptTreeList({});
      
      // 获取角色关联的部门ID列表
      const checkedKeys = await roleService.getRoleDeptIds(roleId);
      
      // 结果日志
      logger.info("获取角色部门树成功", {
        response: {
          roleId,
          checkedKeysCount: checkedKeys.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithoutWrapper(res, {
				depts: deptTree,
				checkedKeys,
			});
    } catch (error: any) {
      consoleLogger.error(`获取角色部门树失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '获取角色部门树失败', 500);
      }
    }
  }

  /**
   * 保存角色授权用户
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '角色管理', businessType: BusinessType.GRANT })
  async authorizeUser(req: AuthRequest, res: Response){
    try {
      // 从请求体或查询参数中获取 roleId 和 userIds
      let roleId = req.body.roleId;
      let userIds = req.body.userIds;
      
      // 请求日志
      consoleLogger.info("保存角色授权用户请求", {
        body: req.body,
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      // 如果请求体中没有，则尝试从查询参数中获取
      if (!roleId && req.query.roleId) {
        roleId = Number(req.query.roleId);
      }
      
      if (!userIds && req.query.userIds) {
        // 处理查询参数中的 userIds，可能是字符串或字符串数组
        const userIdsParam = req.query.userIds;
        if (typeof userIdsParam === 'string') {
          // 如果是逗号分隔的字符串，转换为数组
          if (userIdsParam.includes(',')) {
            userIds = userIdsParam.split(',').map(Number);
          } else {
            userIds = [Number(userIdsParam)];
          }
        } else if (Array.isArray(userIdsParam)) {
          userIds = userIdsParam.map(id => Number(id));
        }
      }
      
      // 保存角色授权用户
      await roleService.authorizeUserRole(roleId, userIds, req.user?.userName || 'admin');
      
      // 结果日志
      logger.info("保存角色授权用户成功", {
        response: {
          roleId,
          userCount: userIds.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '授权成功');
    } catch (error: any) {
      consoleLogger.error(`保存角色授权用户失败: ${error.message}`, {
        requestData: {
          body: req.body,
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '授权失败');
      }
    }
  }

  /**
   * 取消授权用户
   */
  async cancelUserAuthorization(req: AuthRequest, res: Response){
    try {
      const roleId = Number(req.params.roleId);
      const userId = Number(req.params.userId);
      
      // 请求日志
      consoleLogger.info("取消授权用户请求", {
        params: req.params,
        roleId,
        userId,
        operator: req.user?.userName || 'unknown',
      });
      
      // 取消授权用户
      await roleService.cancelUserRoleAuthorization(roleId, userId);
      
      // 结果日志
      logger.info("取消授权用户成功", {
        response: {
          roleId,
          userId,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '取消授权成功');
    } catch (error: any) {
      consoleLogger.error(`取消授权用户失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '取消授权用户失败', 500);
      }
    }
  }

  /**
   * 批量取消授权用户
   */
  async cancelUserAuthorizationBatch(req: AuthRequest, res: Response){
    try {
      const { roleId, userIds } = req.body;
      
      // 请求日志
      consoleLogger.info("批量取消授权用户请求", {
        body: req.body,
        roleId,
        userIds,
        operator: req.user?.userName || 'unknown',
      });
      
      // 批量取消授权用户
      await roleService.cancelUserRoleAuthorizationBatch(roleId, userIds);
      
      // 结果日志
      logger.info("批量取消授权用户成功", {
        response: {
          roleId,
          userIds,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '批量取消授权成功');
    } catch (error: any) {
      consoleLogger.error(`批量取消授权用户失败: ${error.message}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '批量取消授权用户失败', 500);
      }
    }
  }
}

export default new RoleController();